#pragma once

#include <map>

#include "common.h"
#include "ntdproto.h"
//#include "speedmeasure.h"
#include "trend.h"

class NtdConn
{
public:
	NtdConn(evutil_socket_t s, const sockaddr_in& addr, int32 seq, evbuffer * output);
	virtual ~NtdConn();

	void HandleProtoData(NtdProtoData * proto);
	void HandleHandShake(NtdProtoHandShake * proto);
	void HandleFin(NtdProtoFin * proto);

	uint32 GetLastIOTs() { return m_lastIOts; }

private:
	int32 m_initSeq;

	NtdProtoFeedback m_feedback;

	evutil_socket_t m_socket;
	struct sockaddr_in m_addr;
	evbuffer * m_output;

	uint32 m_pktloss;
	int32 m_seqexpt;

	//SpeedMeasure m_sm;
	uint32 m_total;
	uint32 m_tscost;
	uint32 m_tsstart;

	uint32 m_lastIOts;

	bool m_bPacketPair;
	uint64 m_tsFirst;

	bool m_bFin;

	SpearmanTrendDetector inc_dect;
};

class UDPServer : public NtdProtoParser
{
public:
	UDPServer();
	virtual ~UDPServer();
	bool Listen(int port);
	void Stop();
	void OnRead();
	void OnWrite();

	void OnTimer();

	virtual void HandleProtoData(NtdProtoData * proto, void* pContext);
	virtual void HandleHandShake(NtdProtoHandShake * proto, void* pContext);
	virtual void HandleFin(NtdProtoFin * proto, void* pContext);

private:

	evbuffer * m_evbuf_input;
	evbuffer * m_evbuf_output;
	struct event *m_ev;
	evutil_socket_t m_socket;

	uint64 m_lastrcvts;

	//NtdProtoFeedback m_feedback;

	//bool m_bReply;

	//uint32 m_pktloss;
	//uint32 m_seqexpt;

	//SpeedMeasure m_sm;

	std::map<int16, NtdConn*> m_connMap;
	struct event m_timeout;
};